'use strict';
const pkgDir = require('pkg-dir').sync
const path = require('path')
const pathExists = require('path-exists').sync
const fse = require('fs-extra')

const npmInstall = require('npminstall')
const {isObject} = require('@xykj-cli-dev/utils')
const formatPath = require('@xykj-cli-dev/format-path')
const {getDefaultRegistry,getNpmLatesVersion} = require('@xykj-cli-dev/get-npm-info')

class Package {
    constructor(options) {
        console.log('options是否为对象', isObject(options))
        if (!options) {
            throw new Error('Package类的options参数不能为空')
        }
        if (!isObject(options)) {
            throw new Error('Package类的options参数要是一个对象')
        }
        //package 的路径
        this.targetPath = options.targetPath
        // package 的存储路径
        this.storePath = options.storePath
        // packageName
        this.packageName = options.packageName
        // package的版本
        this.packageVersion = options.packageVersion
        // package的缓存目录前缀
        this.cacheFilePathPrefix = this.packageName.replace('/','_')
        console.log('Package 初始化')

    }

    async prepare(){
        if(this.storePath && !pathExists(this.storePath)){
            fse.mkdirpSync(this.storePath) // 将路径中的所有目录创建好
        }
        if(this.packageVersion === 'latest'){
            this.packageVersion = await getNpmLatesVersion(this.packageName)
        }
        console.log(this.packageVersion)
    }

    get cacheFilePath(){
        return path.resolve(this.storePath,`_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`)
    }

    getSpecificCacheFilePath(packageVersion){
        return path.resolve(this.storePath,`_${this.cacheFilePathPrefix}@${packageVersion}@${this.packageName}`)
    }

    // 判断当前package是否存在
    async exists() {
        if(this.storePath){
            await this.prepare()
            console.log(this.cacheFilePath)
            return pathExists(this.cacheFilePath)
        }else{
            return pathExists(this.targetPath)
        }
    }

    // 安装package
    async install() {
        await this.prepare()
        await npmInstall({
            root: this.targetPath,
            storeDir: this.storePath,
            registry: getDefaultRegistry(),
            pkgs: [{
                name: this.packageName, version: this.packageVersion
            }]
        })
    }

    // 更新package
    async update() {
        await this.prepare()
        // 1. 获取最新的npm模块版本号
        const newestPackageVersion = await getNpmLatesVersion(this.packageName)
        // 2. 查询最新版本号对应的路径是否存在
        const latestFilePath = this.getSpecificCacheFilePath(newestPackageVersion)
        // 3. 如果不存在，则直接安装最新版本
        if(!pathExists(latestFilePath)){
            await npmInstall({
                root: this.targetPath,
                storeDir: this.storePath,
                registry: getDefaultRegistry(),
                pkgs: [{
                    name: this.packageName, version: newestPackageVersion
                }]
            })
        }
        this.packageVersion = newestPackageVersion
    }

    // 获取入口文件的路径
    getRootFilePath() {
        function _getRootFile(targetPath){
            // 1. 获取package.json所在目录 (用pkg-dir包)
            const dir = pkgDir(targetPath)
            if (dir) {
                // 2. 读取package.json require
                const pkgFile = require(path.resolve(dir, 'package.json'))
                // 3. 寻找main,找到主文件
                if (pkgFile && pkgFile.main) {
                    // 4. 路径的兼容
                    return formatPath(path.resolve(dir, pkgFile.main))
                }
            }
            return null
        }
        if(this.storePath){
            return _getRootFile(this.cacheFilePath)
        }else{
            return _getRootFile(this.targetPath)
        }
    }
}

module.exports = Package;
